create_file_copy_from_input_at (OstreeRepo *repo,
OstreeRepoCheckoutAtOptions *options,
CheckoutState *state,
+ const char *checksum,
GFileInfo *file_info,
GVariant *xattrs,
GInputStream *input,
replace_mode = GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST;
break;
case OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL:
- /* We don't support copying in union identical */
- g_assert_not_reached ();
+ {
+ replace_mode = GLNX_LINK_TMPFILE_NOREPLACE;
+ struct stat dest_stbuf;
+ if (!glnx_fstatat_allow_noent (destination_dfd, destination_name, &dest_stbuf,
+ AT_SYMLINK_NOFOLLOW, error))
+ return FALSE;
+ if (errno == 0)
+ {
+ /* We do a checksum comparison; see also equivalent code in
+ * checkout_file_hardlink().
+ */
+ OstreeChecksumFlags flags = 0;
+ if (repo->disable_xattrs)
+ flags |= OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS;
+
+ g_autofree char *actual_checksum = NULL;
+ if (!ostree_checksum_file_at (destination_dfd, destination_name,
+ &dest_stbuf, OSTREE_OBJECT_TYPE_FILE,
+ flags, &actual_checksum, cancellable, error))
+ return FALSE;
+
+ if (g_str_equal (checksum, actual_checksum))
+ return TRUE;
+
+ /* Otherwise, fall through and do the link, we should
+ * get EEXIST.
+ */
+ }
+ }
break;
}
cancellable, error))
return FALSE;
- if (!create_file_copy_from_input_at (repo, options, state, source_info, xattrs, input,
+ if (!create_file_copy_from_input_at (repo, options, state, checksum, source_info, xattrs, input,
destination_dfd, destination_name,
cancellable, error))
return glnx_prefix_error (error, "Copy checkout of %s to %s", checksum, destination_name);
set -euo pipefail
-echo "1..$((84 + ${extra_basic_tests:-0}))"
+echo "1..$((85 + ${extra_basic_tests:-0}))"
CHECKOUT_U_ARG=""
CHECKOUT_H_ARGS="-H"
rm tree-with-empty-files -rf
echo "ok checkout --force-copy-zerosized"
+# These should merge, they're identical
+$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files
+$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files
+echo notempty > tree-with-empty-files/anemptyfile.new && mv tree-with-empty-files/anemptyfile{.new,}
+$CMD_PREFIX ostree --repo=repo commit --consume -b tree-with-conflicting-empty-files --tree=dir=tree-with-empty-files
+# Reset back to base
+rm tree-with-empty-files -rf
+$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files
+if $CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-conflicting-empty-files tree-with-empty-files 2>err.txt; then
+ fatal "--union-identical --force-copy-zerosized unexpectedly succeeded with non-identical files"
+fi
+assert_file_has_content err.txt 'error:.*File exists'
+echo "ok checkout --union-identical --force-copy-zerosized"
+
cd ${test_tmpdir}
rm files -rf && mkdir files
mkdir files/worldwritable-dir